package com.happy3w.task.composer;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class TaskDataMode {
    public abstract Object createParams(List<TaskDataDef> inputs, TaskExecuteContext context);
    public abstract void saveResult(Object result, List<TaskDataDef> outputs, TaskExecuteContext context);

    public static final TaskDataMode ArrayMode = new TaskDataMode() {
        @Override
        public Object createParams(List<TaskDataDef> inputs, TaskExecuteContext context) {
            List<Object> params = new ArrayList<>();
            for (TaskDataDef taskDataDef : inputs) {
                params.add(context.getValue(taskDataDef.getName()));
            }
            return params.toArray();
        }

        @Override
        public void saveResult(Object result, List<TaskDataDef> outputs, TaskExecuteContext context) {
            for (int i = 0; i < outputs.size(); i++) {
                TaskDataDef taskDataDef = outputs.get(i);
                Object value = Array.get(result, i);
                context.setValue(taskDataDef.getName(), value);
            }
        }
    };

    public static final TaskDataMode SingleMode = new TaskDataMode() {

        @Override
        public Object createParams(List<TaskDataDef> inputs, TaskExecuteContext context) {
            return context.getValue(inputs.get(0).getName());
        }

        @Override
        public void saveResult(Object result, List<TaskDataDef> outputs, TaskExecuteContext context) {
            context.setValue(outputs.get(0).getName(), result);
        }
    };

    public static final TaskDataMode MapMode = new TaskDataMode() {

        @Override
        public Object createParams(List<TaskDataDef> inputs, TaskExecuteContext context) {
            Map<String, Object> params = new HashMap<>();
            for (TaskDataDef taskDataDef : inputs) {
                String name = taskDataDef.getName();
                params.put(name, context.getValue(name));
            }
            return params;
        }

        @Override
        public void saveResult(Object result, List<TaskDataDef> outputs, TaskExecuteContext context) {
            Map<String, Object> mapResult = (Map<String, Object>) result;
            for (TaskDataDef output : outputs) {
                String name = output.getName();
                Object value = mapResult.get(name);
                context.setValue(name, value);
            }
        }
    };
}
